#include "main.pb.h"
#include <brpc/server.h>
#include <butil/logging.h>
#include <brpc/channel.h>
#include <gflags/gflags.h>
#include <thread>

void callback(brpc::Controller* controller, example::EchoResponse* response)
{
    std::unique_ptr<brpc::Controller> cntl_guard(controller);
    std::unique_ptr<example::EchoResponse> rsp_guard(response);
    if (controller->Failed())
    {
        std::cout << "rpc 调用失败" << controller->ErrorText() << std::endl;
        return;
    }
    std::cout << "收到响应：" << response->message() << std::endl;
}

int main(int argc, char* argv[])
{
    //1.构造channel信道 连接服务器
    brpc::ChannelOptions options;
    options.connect_timeout_ms = -1;    //连接等待超时时间， -1表示一直等待
    options.timeout_ms = -1;            //rpc请求等待超时时间 -1一直等待
    options.max_retry = 3;              //请求重试次数    
    options.protocol = "baidu_std";     //序列化协议 默认使用baidu_std

    brpc::Channel channel;
    int ret = channel.Init("127.0.0.1:8080", &options);
    if(ret = -1)
    {
        std::cout << "初始化信道失败 \n";
    }
    //2.构造EchoService_Stub对象 用于进行rpc调用
    example::EchoService_Stub stub(&channel);
    //3.进行rpc调用 
    example::EchoRequest req;
    /*
      void Echo(::google::protobuf::RpcController* controller,  //上下文管理对象
                       const ::example::EchoRequest* request,
                       ::example::EchoResponse* response,
                       ::google::protobuf::Closure* done);*/
    req.set_message("hello world");
    brpc::Controller *cntl = new brpc::Controller();    //防止还没回调 上下文被释放 放堆上
    example::EchoResponse* rsp = new example::EchoResponse();

    //stub.Echo(cntl, &req, rsp, nullptr);    //同步调用
    // if(cntl->Failed())
    // {
    //     std::cout << "rpc 调用失败" << cntl->ErrorText() << std::endl;
    // }
    //std::cout << "收到响应：" << rsp->message() << std::endl;

    auto closure = google::protobuf::NewCallback(callback, cntl, rsp);
    stub.Echo(cntl, &req, rsp, closure);    //异步调用
    std::cout << "异步调用结束！" << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(3));
    
    delete cntl;
    delete rsp;

    return 0;
}